﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using EventMgrLib;
using SmartMotion.Core;
using Sunny.UI;
using WeifenLuo.WinFormsUI.Docking;

namespace SmartMotion.AllPages.DockPanels
{
    public partial class FrmEdit : DockContent
    {
       
        public Flow EditFLow { get; private set; }
        private BindingList<ActionItem> _actions;
        private ToolMgr _toolMgr;
        private EventMgr _em;
        public FrmEdit()
        {
            InitializeComponent();
            grid.AutoGenerateColumns = false;
            grid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCellsExceptHeaders;
            grid.AllowDrop = true;
            grid.AllowUserToAddRows = false;
            grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            grid.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            HideOnClose = true;
            CheckForIllegalCrossThreadCalls = false;
            grid.DataError += Grid_DataError;
        }

        private void Grid_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            //throw new NotImplementedException();
        }   

        public void LoadFlow(Flow flow)
        {
            _toolMgr = ToolMgr.Ins;
            _em = EventMgr.Ins;
            EditFLow = flow;
            _actions = new BindingList<ActionItem>(EditFLow.ActionItems);
            grid.DataSource = _actions;
        }

        private void FrmEdit_Load(object sender, EventArgs e)
        {
            grid.DragEnter += Grid_DragEnter;
            grid.DragDrop += Grid_DragDrop;
            _em.GetEvent<PropertyValueChanged>().Subscribe(ValueChanged);
        }

        private void ValueChanged()
        {
            if (grid.CurrentRow!=null)
            {
                grid.InvalidateRow(grid.CurrentRow.Index);
            }
        }

        private void Grid_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(typeof(TreeNode)))
            {
                e.Effect = DragDropEffects.Copy;
            }
        }

        private void Grid_DragDrop(object sender, DragEventArgs e)
        {
            if (e.Effect==DragDropEffects.Copy)
            {
                TreeNode node;
                if (e.Data.GetDataPresent(typeof(TreeNode)))
                {
                    node = (TreeNode)(e.Data.GetData(typeof(TreeNode)));
                }
                else
                {
                    return;
                }

                string toolNmae = node.Text;
                ActionItem dragTool = _toolMgr.Tools.Find(t => t.ItemName == toolNmae);
                if (dragTool==null) return;
                int insert = GetRow(grid, e);
                ActionItem newItem = dragTool.CopyFromTool();
                newItem.Index = grid.Rows.Count;
                newItem.Description = dragTool.Description;
                if (insert>=0)
                {
                    _actions.Insert(insert,newItem);
                }
                else
                {
                    _actions.Add(newItem);
                }

            }
        }
        private int GetRow(DataGridView gridView, DragEventArgs e)
        {
            //将屏幕坐标转换为控件坐标之后获取该坐标下DataGridView的行和列
            var clientPt = gridView.PointToClient(new Point(e.X, e.Y));
            var ht = gridView.HitTest(clientPt.X, clientPt.Y);
            return ht.RowIndex;
        }


        private void FrmEdit_FormClosing(object sender, FormClosingEventArgs e)
        {
            grid.DragEnter -= Grid_DragEnter;
            grid.DragDrop -= Grid_DragDrop;
        }

        private void grid_SelectionChanged(object sender, EventArgs e)
        {
            if (grid?.CurrentRow==null) return;
            int index = grid.CurrentRow.Index;
            if (index<0||index>=EditFLow.ActionItems.Count) return;
            _em.GetEvent<SelectActionChanged>().Publish(EditFLow.ActionItems[index]);
        }

        private void grid_CurrentCellDirtyStateChanged(object sender, EventArgs e)
        {
            grid.CommitEdit(DataGridViewDataErrorContexts.Commit);
            grid_SelectionChanged(null, null);
        }

        private void grid_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (grid?.CurrentRow==null) return;
            int index = grid.CurrentRow.Index;
            if (index<0||index>=EditFLow.ActionItems.Count) return;

            if (EditFLow.ActionItems[index].GetConfigForm() is UIForm configForm)
            {
                configForm.ShowDialog();

                grid_SelectionChanged(null, null);

            }
        }

        #region 右键菜单

        private void 上移ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (grid.SelectedIndex<=0) return;
            Swap(EditFLow.ActionItems,grid.SelectedIndex,grid.SelectedIndex-1);
            grid.InvalidateRow(grid.SelectedIndex);
            grid.InvalidateRow(grid.SelectedIndex-1);
        }

        private void 下移ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (grid.SelectedIndex>=grid.RowCount-1 || grid.SelectedIndex<0) return;
            Swap(EditFLow.ActionItems, grid.SelectedIndex, grid.SelectedIndex +1);
            grid.InvalidateRow(grid.SelectedIndex);
            grid.InvalidateRow(grid.SelectedIndex +1);
        }

        void Swap<T>(IList<T> list, int index1, int index2)
        {
            (list[index1], list[index2]) = (list[index2], list[index1]);
        }

        private void 删除ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (grid.SelectedIndex>-1) _actions.RemoveAt(grid.SelectedIndex);
 
        }

        private void 复制ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int copyIndex = grid.SelectedIndex;
            if (copyIndex<0) return;
            ActionItem newItem = _actions[copyIndex].CopyFromTool();
            newItem.Index = grid.Rows.Count;
            newItem.Description = _actions[copyIndex].ItemName;
            _actions.Insert(copyIndex+1,newItem);
        }

        #endregion
    }
}
